package org.lop.modules.utils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.beanutils.BeanComparator;
import org.apache.commons.collections.comparators.ComparableComparator;
import org.apache.commons.collections.comparators.ComparatorChain;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order;

/**
 * 基于apache的Comparator工具.
 * 
 * @author 潘瑞峥
 * @date 2013-6-6
 */
public class ComparatorUtils {

	private ComparatorUtils() {
	}

	/**
	 * 创建Comparator, null排在最底.
	 * 
	 * @param sort
	 * @return
	 */
	@SuppressWarnings( "rawtypes" )
	public static Comparator createComparator( Sort sort ) {
		return createComparator( sort, true );
	}

	/**
	 * 创建Comparator, 根据nullLow判断null排列位置.
	 * 
	 * @param sort
	 * @param isNullLow
	 * @return
	 */
	@SuppressWarnings( "rawtypes" )
	public static Comparator createComparator( Sort sort, boolean isNullLow ) {
		List<BeanComparator> beanComparators = new ArrayList<BeanComparator>();

		/* 正序. */
		Comparator comparatorNatural = ComparableComparator.getInstance();
		comparatorNatural = org.apache.commons.collections.ComparatorUtils.naturalComparator();

		/* 逆序. */
		Comparator comparatorReversed = ComparableComparator.getInstance();
		comparatorReversed = org.apache.commons.collections.ComparatorUtils.reversedComparator( comparatorReversed );

		/* 是否null排在最底. */
		if ( isNullLow ) {
			comparatorNatural = org.apache.commons.collections.ComparatorUtils.nullLowComparator( comparatorNatural );
			comparatorReversed = org.apache.commons.collections.ComparatorUtils.nullLowComparator( comparatorReversed );
		} else {
			comparatorNatural = org.apache.commons.collections.ComparatorUtils.nullHighComparator( comparatorNatural );
			comparatorReversed = org.apache.commons.collections.ComparatorUtils.nullHighComparator( comparatorReversed );
		}

		for ( Order order : sort ) {
			if ( order.isAscending() ) {
				beanComparators.add( new BeanComparator( order.getProperty(), comparatorNatural ) );
			} else {
				beanComparators.add( new BeanComparator( order.getProperty(), comparatorReversed ) );
			}
		}

		ComparatorChain comparatorChain = new ComparatorChain( beanComparators );

		return comparatorChain;
	}

}